using MediatR;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RabbitTraceability.Api.Applications.Command;
using RabbitTraceability.Api.Dtos.Request;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Linq;
using RabbitTraceability.Api.Dtos.Response;
using ErrorCode;

namespace RabbitTraceability.Api.Controllers
{
    /// <summary>
    /// 溯源信息控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class TraceabilityController : ControllerBase
    {
        private readonly IMediator _mediator;
        private readonly ILogger<TraceabilityController> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mediator">中介者</param>
        /// <param name="logger">日志记录器</param>
        public TraceabilityController(IMediator mediator, ILogger<TraceabilityController> logger)
        {
            _mediator = mediator;
            _logger = logger;
        }

        /// <summary>
        /// 添加溯源信息
        /// </summary>
        /// <param name="request">添加溯源信息请求</param>
        /// <returns>操作结果</returns>
        [HttpPost]
        [Authorize]
        public async Task<IActionResult> AddTraceabilityInfo([FromBody] AddTraceabilityInfoRequestDto request)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            var command = new AddTraceabilityInfoCommand
            {
                ProductName = request.ProductName,
                ProductionBatch = request.ProductionBatch,
                ShelfLife = request.ShelfLife,
                ProductionLicense = request.ProductionLicense,
                Manufacturer = request.Manufacturer,
                CoverImage = request.CoverImage
            };

            var result = await _mediator.Send(command);

            return Ok(new { success = true, data = result });
        }

        /// <summary>
        /// 分页查询溯源信息
        /// </summary>
        /// <param name="command">查询条件</param>
        /// <returns>分页结果</returns>
        [HttpGet]
        [AllowAnonymous] // 允许匿名访问
        public async Task<ApiResult<ApiPaging<TraceabilityInfoDto>>> QueryTraceabilityInfo([FromQuery] QueryTraceabilityInfoCommand command)
        {
            try
            {
                _logger.LogInformation("接收到查询溯源信息请求，页码：{PageIndex}，每页记录数：{PageSize}", command.PageIndex, command.PageSize);
                
                // 发送查询命令
                var result = await _mediator.Send(command);
                
                return ApiResult<ApiPaging<TraceabilityInfoDto>>.SuccessWithData(result);
            }
            catch (ApiException ex)
            {
                _logger.LogWarning("查询溯源信息时发生业务异常: {Message}", ex.Message);
                return ApiResult<ApiPaging<TraceabilityInfoDto>>.Fail(ex.Message, ex.Code);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询溯源信息时发生未处理的异常: {Message}", ex.Message);
                return ApiResult<ApiPaging<TraceabilityInfoDto>>.Fail("查询溯源信息失败，请稍后再试", ResultCode.服务器错误);
            }
        }

        /// <summary>
        /// 根据溯源编号查询详情
        /// </summary>
        /// <param name="id">溯源编号</param>
        /// <returns>溯源详情</returns>
        [HttpGet("{id}")]
        [AllowAnonymous] // 允许匿名访问
        public async Task<ApiResult<TraceabilityInfoDto>> GetTraceabilityDetail(string id)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(id))
                {
                    return ApiResult<TraceabilityInfoDto>.Fail("溯源编号不能为空", ResultCode.参数错误);
                }

                _logger.LogInformation("接收到查询溯源详情请求，溯源编号：{TraceabilityId}", id);
                
                var command = new GetTraceabilityDetailCommand(id);
                var result = await _mediator.Send(command);

                if (result == null)
                {
                    return ApiResult<TraceabilityInfoDto>.Fail("未找到相关溯源信息", ResultCode.数据不存在);
                }

                return ApiResult<TraceabilityInfoDto>.SuccessWithData(result);
            }
            catch (ApiException ex)
            {
                _logger.LogWarning("查询溯源详情时发生业务异常: {Message}", ex.Message);
                return ApiResult<TraceabilityInfoDto>.Fail(ex.Message, ex.Code);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询溯源详情时发生未处理的异常: {Message}", ex.Message);
                return ApiResult<TraceabilityInfoDto>.Fail("查询溯源详情失败，请稍后再试", ResultCode.服务器错误);
            }
        }

        /// <summary>
        /// 删除溯源信息
        /// </summary>
        /// <param name="id">溯源编号</param>
        /// <returns>删除结果</returns>
        [HttpDelete("{id}")]
        [Authorize] // 需要授权
        public async Task<ApiResult<bool>> DeleteTraceabilityInfo(string id)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(id))
                {
                    return ApiResult<bool>.Fail("溯源编号不能为空", ResultCode.参数错误);
                }

                _logger.LogInformation("接收到删除溯源信息请求，溯源编号：{TraceabilityId}", id);
                
                var command = new DeleteTraceabilityInfoCommand(id);
                var result = await _mediator.Send(command);

                _logger.LogInformation("删除溯源信息完成，溯源编号：{TraceabilityId}，结果：{Result}", id, result);
                
                return ApiResult<bool>.SuccessWithData(result);
            }
            catch (ApiException ex)
            {
                _logger.LogWarning("删除溯源信息时发生业务异常: {Message}", ex.Message);
                return ApiResult<bool>.Fail(ex.Message, ex.Code);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除溯源信息时发生未处理的异常: {Message}", ex.Message);
                return ApiResult<bool>.Fail("删除溯源信息失败，请稍后再试", ResultCode.服务器错误);
            }
        }

        /// <summary>
        /// 修改溯源信息
        /// </summary>
        /// <param name="id">溯源编号</param>
        /// <param name="request">修改溯源信息请求</param>
        /// <returns>修改结果</returns>
        [HttpPut("{id}")]
        [Authorize] // 需要授权
        public async Task<ApiResult<bool>> UpdateTraceabilityInfo(string id, [FromBody] UpdateTraceabilityInfoRequestDto request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(id))
                {
                    return ApiResult<bool>.Fail("溯源编号不能为空", ResultCode.参数错误);
                }

                if (!ModelState.IsValid)
                {
                    var errors = string.Join("; ", ModelState.Values
                        .SelectMany(v => v.Errors)
                        .Select(e => e.ErrorMessage));
                    return ApiResult<bool>.Fail(errors, ResultCode.参数错误);
                }

                _logger.LogInformation("接收到修改溯源信息请求，溯源编号：{TraceabilityId}", id);
                
                var command = new UpdateTraceabilityInfoCommand
                {
                    TraceabilityId = id,
                    ProductName = request.ProductName,
                    ProductionBatch = request.ProductionBatch,
                    ShelfLife = request.ShelfLife,
                    ProductionLicense = request.ProductionLicense,
                    Manufacturer = request.Manufacturer,
                    CoverImage = request.CoverImage
                };
                
                var result = await _mediator.Send(command);

                _logger.LogInformation("修改溯源信息完成，溯源编号：{TraceabilityId}，结果：{Result}", id, result);
                
                return ApiResult<bool>.SuccessWithData(result);
            }
            catch (ApiException ex)
            {
                _logger.LogWarning("修改溯源信息时发生业务异常: {Message}", ex.Message);
                return ApiResult<bool>.Fail(ex.Message, ex.Code);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "修改溯源信息时发生未处理的异常: {Message}", ex.Message);
                return ApiResult<bool>.Fail("修改溯源信息失败，请稍后再试", ResultCode.服务器错误);
            }
        }
    }
}